'''
作品名：MinecraftSkinDownloader
Github仓库地址:https://github.com/NewbieXvwu/MinecraftSkinDownloader
Gitee仓库地址:https://gitee.com/NewbieXvwu/MinecraftSkinDownloader
关于本程序：这是一个可以简单地下载任何Minecraft正版玩家的皮肤的软件，使用Python编写，由NewbieXvwu维护。
作者：NewbieXvwu
'''


version_int=2.7#程序主版本号
ispreview=False#程序是否是预览版
previewversion="0"#预览版本号（不自动更新）
if ispreview:#生成字符串版的版本号
    version="v"+str(version_int)+" Preview "+previewversion
else:
    version="v"+str(version_int)

#导入本地库
import sys
import os
import json
import base64
import tkinter
from urllib.request import urlretrieve
import zipfile
import shutil
from tkinter import messagebox
import threading
import platform
import ctypes
import time

try:
    import winreg
except:
    pass

# 判断当前操作系统是否为linux
def isLinux():
    return platform.architecture()[1]=="ELF"
global ThreadShouldStop
ThreadShouldStop=False

# 创建一个图形用户界面，当用户尝试关闭窗口时，会弹出一个错误消息框。
def on_closing():
    tkinter.messagebox.showerror("错误","正在安装必要的运行库！\n强制退出会造成运行库损坏！")


#尝试安装并导入第三方库
try:
    import requests

# 没有安装requests的情况
except:
    from tkinter import *
    import tkinter
    from tkinter.ttk import *

    def sc_main_():
        sc_=Tk()
        #窗口居中，以及窗口大小与位置
        scw=sc_.winfo_screenwidth()
        sch=sc_.winfo_screenheight()
        w=300
        h=200
        x=(scw-w)/2
        y=(sch-h)/2
        sc_.title("正在安装运行库")
        sc_.geometry("%dx%d+%d+%d"%(w,h,x,y))
        sc_.maxsize(w,h)
        sc_.minsize(w,h)

        #为tkinter窗口设置图标logo.ico，如果本地没有图标文件，那么尝试从两个不同的在线源下载图标文件。
        try:
            sc_.iconbitmap('logo.ico')
        except:
            try:
                urlretrieve("https://gitee.com/NewbieXvwu/MinecraftSkinDownloader/raw/main/logo.ico","logo.ico")
                sc_.iconbitmap('logo.ico')
            except:
                try:
                    urlretrieve("https://github.com/NewbieXvwu/MinecraftSkinDownloader/raw/main/logo.ico","logo.ico")
                    sc_.iconbitmap('logo.ico')
                except:
                    pass

        # 使tkinter窗口在高DPI屏幕上正确显示
        try:
            ctypes.windll.shcore.SetProcessDpiAwareness(1)#高DPI适配
            ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(0)
            sc_.tk.call('tk', 'scaling', ScaleFactor/75)
        except:
            pass

        # 创建一个进度条在窗口显示
        def showmain():
            while True:
                for i in range(100):
                    try:
                        # 每次更新加1
                        pb_['value'] = i + 1
                        # 更新画面
                        sc_.update()
                        time.sleep(0.05)
                    except:
                        exit()
                for i in range(100):
                    try:
                        # 每次更新减1
                        pb_['value'] = 100 - i
                        # 更新画面
                        sc_.update()
                        time.sleep(0.05)
                    except:
                        exit()

        # 强制终止所有Python相关进程
        def ThreadStop():
            # 如果有一个exe没有停止，就循环
            while True:
                try:
                    if ThreadShouldStop:
                        #sc_.destroy()
                        try:
                            os.system("taskkill -f -im python.exe")
                            os.system("taskkill -f -im pythonw.exe")
                            os.system("taskkill -f -im py.exe")
                            os.system("taskkill -f -im pyw.exe")
                            os.system("taskkill -f -im python3.exe")
                            os.system("taskkill -f -im pythonw3.exe")
                            os.system("taskkill -f -im py3.exe")
                            os.system("taskkill -f -im pyw3.exe")
                        except:
                            exit()
                except:
                    pass
                time.sleep(0.1)

        # 创建代码守护ThreadStop线程 # 主程序退出该线程会自动终止
        run___=threading.Thread(target=ThreadStop)
        run___.daemon=True
        run___.start()

        # 多线程运行主函数，防止主线程GUI卡死
        def show():
            run__=threading.Thread(target=showmain)
            run__.start()

        # 提示标签
        lb1_=Label(sc_,text="正在安装程序必要的运行库……",font=("宋体",13))
        lb1_.place(x=30,y=30)

        # 详细状态标签
        lb2_=Label(sc_,text="  正在安装：requests\n\n安装完毕后请手动重启程序",font=("宋体",10))
        lb2_.place(x=150,y=90,anchor="center")

        # 显示进度条
        pb_=Progressbar(sc_,length=240,mode='indeterminate',orient=tkinter.HORIZONTAL)
        pb_.place(x=30,y=130)

        # 启动主函数线程
        show()
        sc_.protocol('WM_DELETE_WINDOW', on_closing)
        sc_.mainloop() # 启动GUI主循环

    # 在新线程中运行GUI主函数
    run___=threading.Thread(target=sc_main_)
    run___.start()

    # 用清华镜像源安装requests库，执行系统命令并获取输出，读取命令执行的全部结果
    result=os.popen("pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests").read()

    # 如果安装requests成功
    if "Successfully installed" in result:
        # 成功后尝试导入requests库，验证安装是否真正成功
        import requests
        from requests import delete
        ThreadShouldStop=True
    # 安装requests失败
    else:
        # 如果用户选择"是"，自动打开GitHub issue页面
        if tkinter.messagebox.askyesno("错误","运行库安装失败，程序无法继续运行！\n请把以下内容提交给开发者：\n"+result+"\n是否要提交错误？"):os.startfile("https://github.com/NewbieXvwu/MinecraftSkinDownloader/issues/new?assignees=&labels=bug&template=bug_report.yml&title=%5B%E6%BC%8F%E6%B4%9E%5D+%E6%97%A0%E6%B3%95%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96%E5%BA%93")
        exit()

    # 尝试导入ttkthemes
    try:
        import ttkthemes

    # 无法导入，没有安装ttkthemes
    except:
        # 尝试安装ttkthemes
        result=os.popen("pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ttkthemes").read()
        # 安装ttkthemes成功
        if "Successfully installed" in result:
            # 安装成功就导入库
            import ttkthemes
            ThreadShouldStop=True
        # 安装ttkthemes失败
        else:
            # 如果用户选择"是"，自动打开GitHub issue页面
            if tkinter.messagebox.askyesno("错误","运行库安装失败，程序无法继续运行！\n请把以下内容提交给开发者：\n"+result+"\n是否要提交错误？"):os.startfile("https://github.com/NewbieXvwu/MinecraftSkinDownloader/issues/new?assignees=&labels=bug&template=bug_report.yml&title=%5B%E6%BC%8F%E6%B4%9E%5D+%E6%97%A0%E6%B3%95%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96%E5%BA%93")
            exit()


else:#安装了requests
    # 尝试导入ttkthemes库
    try:
        import ttkthemes
    # 没有安装ttkthemes
    except:
        from tkinter import *
        import tkinter
        from tkinter.ttk import *

        # 创建窗口
        def sc_main_():
            sc_=Tk()
            #窗口居中，以及窗口大小与位置
            scw=sc_.winfo_screenwidth()
            sch=sc_.winfo_screenheight()
            w=300
            h=200
            x=(scw-w)/2
            y=(sch-h)/2
            sc_.title("正在安装运行库")
            sc_.geometry("%dx%d+%d+%d"%(w,h,x,y))
            sc_.maxsize(w,h)
            sc_.minsize(w,h)

            # 从双源尝试下载Logo
            try:
                sc_.iconbitmap('logo.ico')
            except:
                try:
                    urlretrieve("https://gitee.com/NewbieXvwu/MinecraftSkinDownloader/raw/main/logo.ico","logo.ico")
                    sc_.iconbitmap('logo.ico')
                except:
                    try:
                        urlretrieve("https://github.com/NewbieXvwu/MinecraftSkinDownloader/raw/main/logo.ico","logo.ico")
                        sc_.iconbitmap('logo.ico')
                    except:
                        pass

            # 使tkinter窗口在高DPI屏幕上正确显示
            try:
                ctypes.windll.shcore.SetProcessDpiAwareness(1)
                ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(0)
                sc_.tk.call('tk', 'scaling', ScaleFactor/75)
            except:
                pass

            # 创建一个进度条在窗口显示
            def showmain():
                while True:
                    for i in range(100):
                        try:
                            # 每次更新加1
                            pb_['value'] = i + 1
                            # 更新画面
                            sc_.update()
                            time.sleep(0.05)
                        except:
                            exit()
                    for i in range(100):
                        try:
                            # 每次更新减1
                            pb_['value'] = 100 - i
                            # 更新画面
                            sc_.update()
                            time.sleep(0.05)
                        except:
                            exit()

            # 强制终止所有Python相关进程
            def ThreadStop():
                while True:
                    try:
                        if ThreadShouldStop:
                            #sc_.destroy()
                            try:
                                os.system("taskkill -f -im python.exe")
                                os.system("taskkill -f -im pythonw.exe")
                                os.system("taskkill -f -im py.exe")
                                os.system("taskkill -f -im pyw.exe")
                                os.system("taskkill -f -im python3.exe")
                                os.system("taskkill -f -im pythonw3.exe")
                                os.system("taskkill -f -im py3.exe")
                                os.system("taskkill -f -im pyw3.exe")
                            except:
                                exit()
                    except:
                        pass
                    time.sleep(0.1)

            # 创建代码守护ThreadStop线程 # 主程序退出该线程会自动终止
            run___=threading.Thread(target=ThreadStop)
            run___.start()

            # 多线程运行主函数，防止主线程GUI卡死
            def show():
                run__=threading.Thread(target=showmain)
                run__.start()

            # 主提示标签
            lb1_=Label(sc_,text="正在安装程序必要的运行库……",font=("宋体",13))
            lb1_.place(x=30,y=30)

            # 详细状态标签
            lb2_=Label(sc_,text="  正在安装：ttkthemes\n\n安装完毕后请手动重启程序",font=("宋体",10))
            lb2_.place(x=150,y=90,anchor="center")

            # 进度条
            pb_=Progressbar(sc_,length=240,mode='indeterminate',orient=tkinter.HORIZONTAL)
            pb_.place(x=30,y=130)

            # 调用show()开始执行主函数
            show()

            # 启动GUI主循环
            sc_.protocol('WM_DELETE_WINDOW', on_closing)
            sc_.mainloop()

        # 创建守护线程运行sc_main_函数，确保主程序退出时该线程自动终止
        run___=threading.Thread(target=sc_main_)
        run___.daemon=True
        run___.start()

        # 安装ttkthemes库
        result=os.popen("pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ttkthemes").read()
        # 安装ttkthemes成功
        if "Successfully installed" in result:
            # 引入ttkthemes库
            import ttkthemes
            ThreadShouldStop=True
        # 安装ttkthemes失败
        else:
            if tkinter.messagebox.askyesno("错误","运行库安装失败，程序无法继续运行！\n请把以下内容提交给开发者：\n"+result+"\n是否要提交错误？"):os.startfile("https://github.com/NewbieXvwu/MinecraftSkinDownloader/issues/new?assignees=&labels=bug&template=bug_report.yml&title=%5B%E6%BC%8F%E6%B4%9E%5D+%E6%97%A0%E6%B3%95%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96%E5%BA%93")
            exit()


#定义主函数
def getzbmain():#主函数
    # 获取输入框e中的文本作为玩家ID
    id_=e.get()

    # 如果ID为空，显示错误对话框"请填写内容！"
    if id_=="":
        tkinter.messagebox.showerror(title='错误', message='请填写内容！') 
        e.focus_set()
    else:
        zt.set("状态：正在向Mojang请求玩家的UUID……")
        # 构造Mojang API请求URL
        url1="https://api.mojang.com/users/profiles/minecraft/"+id_
        # 用requests发送GET请求获取玩家数据
        r = requests.get(url1)

        del url1 #删除url1
        status_code=r.status_code # 获取HTTP响应的状态码

        # 检查HTTP状态码，如果不是200，显示错误信息
        if not status_code==200:
            zt.set("状态：Bugjump出现错误，请检查你的输入！")
        del status_code #删除

        zt.set("状态：读取UUID中……")
        # 将变量r的内容从响应对象转换为文本格式。
        r=r.text
        # 将文本格式的 JSON 数据解析为 Python 的字典格式。
        r=json.loads(r)

        # 尝试JSON数据中获取id对应的值，并将其赋值给变量 uuid。
        try:
            uuid=r['id']
        except:
            zt.set("状态：Bugjump出现错误，请检查你的输入！")
        del r #删除

        # 构造请求玩家皮肤信息的 URL，将uuid接到URL后面，发送 GET 请求
        zt.set("状态：向Mojang请求下载皮肤的地址中……")
        url2="https://sessionserver.mojang.com/session/minecraft/profile/"+uuid
        r = requests.get(url2)

        del url2
        # 获取HTTP响应的状态码
        status_code=r.status_code
        # 如果HTTP状态码不是200，显示错误信息
        if not status_code==200:
            zt.set("状态：Bugjump出现错误，请检查你的输入！")
        del status_code

        zt.set("状态：读取皮肤下载地址中……")
        r=r.text # 从响应对象转换为文本格式。
        r=json.loads(r) # 将文本格式的 JSON 数据解析为 Python 的字典格式。
        properties=r["properties"] # 获取properties键对应的值
        del r

        # 从API响应中提取包含皮肤信息的 Base64 编码字符串，对其进行解码，得到 JSON 格式的字符串，
        # 然后解析为 Python 的字典格式
        # 从字典中提取皮肤的下载地址。
        properties=properties[0]
        properties=properties["value"]
        zt.set("状态：解码皮肤下载地址中……")
        properties=base64.b64decode(properties)
        properties=properties.decode()
        properties=json.loads(properties)
        url3=properties["textures"]
        del properties

        # 从API响应中提取玩家的披风和皮肤的下载地址
        havecape=False
        try:
            cape=url3["CAPE"]
            cape=cape["url"]
            filename=id_+'_cape.png'
            zt.set("状态：成功获取披风下载直链，正在尝试下载……")
            urlretrieve(cape,filename)
            havecape=True
        except:
            pass
        # 从url3字典中提取皮肤的信息
        url3=url3["SKIN"]

        # 尝试获取皮肤的模型信息
        try:
            isalex=url3["metadata"]
            isalex=isalex["model"]
        except:
            isalex=""

        # 从 SKIN 字典中提取皮肤的下载地址，用玩家的id_ 和.png 作为文件名保存皮肤文件
        url3=url3["url"]
        filename=id_+'.png'
        zt.set("状态：成功获取皮肤下载直链，正在尝试下载……")
        urlretrieve(url3,filename)
        del url3
        del filename

        # 显示不同的下载完成消息
        if havecape:
            exit_=str(tkinter.messagebox.showwarning(title="下载完毕", message="下载完毕！此玩家还拥有披风，已同时下载！"))
        else:
            exit_=str(tkinter.messagebox.showwarning(title="下载完毕", message="下载完毕！"))

        zt.set("状态：待命")
        lb2.config(textvariable=zt)
        # 检查当前操作系统是否不是 Linux
        if not isLinux:
            # 如果当前操作系统不是 Linux，显示一个“确认”和“取消”按钮的消息框。
            exit_=tkinter.messagebox.askyesno(title="下载完毕", message="下载完毕！按“确认”打包皮肤成材质包，或者按“取消”打开文件！")

            # 如果用户选择确定
            if exit_==True:
                # 尝试删除旧的临时目录
                try:
                    file=".\\"+id_
                    shutil.rmtree(file)
                    del file
                except:
                    zt.set("状态：正在删除旧的临时目录……")

                # 更新状态信息
                zt.set("状态：正在创建新的临时目录……")
                lb2.config(textvariable=zt)
                # 创建新的临时目录
                file="./"+id_
                os.mkdir(file)
                del file

                # 创建Minecraft材质包，目录结构、下载和复制文件。
                zt.set("状态：正在创建材质包说明文件……")
                lb2.config(textvariable=zt)
                filename = './'+id_+"/pack.mcmeta"
                mcmeta="{\"pack\":{\"pack_format\":7,\"description\":\"§c",id_,"\'s Skin Resourcepack\"}}"
                with open(filename, 'w') as file_object:
                    file_object.write("{\"pack\":{\"pack_format\":4,\"description\":\"§cSkin Resourcepack\"}}")
                del filename
                del mcmeta
                zt.set("状态：正在下载材质包Logo……")
                lb2.config(textvariable=zt)
                url3="https://pic.downk.cc/item/5ff174673ffa7d37b35bb165.png"
                filename="./"+id_+"/pack.png"
                urlretrieve(url3,filename)
                del url3
                del filename
                zt.set("状态：正在创建皮肤目录……")
                lb2.config(textvariable=zt)
                file="./"+id_+"/assets"
                os.mkdir(file)
                del file
                file="./"+id_+"/assets/minecraft"
                os.mkdir(file)
                del file
                file="./"+id_+"/assets/minecraft/textures"
                os.mkdir(file)
                del file
                file="./"+id_+"/assets/minecraft/textures/entity"
                os.mkdir(file)
                del file

                # 复制皮肤文件到指定目录，将材质包压缩为一个 ZIP 文件
                zt.set("状态：正在复制皮肤文件……")
                lb2.config(textvariable=zt)
                # 根据isalex的值，构造复制皮肤文件的命令。
                if isalex=="slim":
                    cmd="copy "+id_+".png .\\"+id_+"\\assets\\minecraft\\textures\\entity\\alex.png"
                    os.system(cmd)
                else:
                    cmd="copy "+id_+".png .\\"+id_+"\\assets\\minecraft\\textures\\entity\\steve.png"
                    os.system(cmd)
                del cmd
                zt.set("状态：正在压缩材质包……")
                lb2.config(textvariable=zt)
                shutil.make_archive("Skin_"+id_,'zip',id_)
                zt.set("状态：正在删除临时目录……")
                lb2.config(textvariable=zt)
                file=".\\"+id_
                shutil.rmtree(file)
                del file

                zt.set("状态：待命")
                # 检查当前目录下是否存在 .minecraft/resourcepacks文件夹
                if os.path.exists(".\\.minecraft\\resourcepacks"):
                    # 如果存在，显示一个有“确认”和“取消”按钮的消息框
                    exit_=tkinter.messagebox.askyesno(title="创建材质包成功", message="成功创建材质包！\n注意：材质包会将游戏内的所有玩家的皮肤都替换成你想要的皮肤，可能会导致一些小问题！\n检测到程序目录下有Minecraft安装，如果要直接导入Minecraft，请按下“确认”，否则请按下“取消”打开材质包。")

                    # 如果用户点击确认，将压缩后的材质包文件复制到 .minecraft/resourcepacks文件夹
                    if exit_==True:
                        cmd="copy Skin_"+id_+".zip .\\.minecraft\\resourcepacks\\"+id_+".zip"
                        os.system(cmd)
                        del cmd
                        # 显示一个消息框，提示用户是否要打开材质包文件夹。
                        exit_=tkinter.messagebox.askyesno(title="导入成功", message="导入成功！\n是否要打开材质包文件夹？")
                        # 如果点击“确认”，则打开 .minecraft/resourcepacks文件夹
                        if exit_==True:
                            start="start \"\" .\\.minecraft\\resourcepacks\\"
                            os.system(start)
                        del exit_
                    # 如果用户点击“取消”，则打开材质包文件
                    else:
                        start="start \"\" "+"\""+id_+'.zip'+"\""
                        os.system(start)

                # 如果不存在.minecraft/resourcepacks文件夹
                else:
                    # 显示一个带消息框，提示用户是否要打开材质包文件
                    exit_=tkinter.messagebox.askyesno(title="创建材质包成功", message="创建材质包成功！注意：材质包会将游戏内的所有玩家的皮肤都替换成你想要的皮肤，可能会导致一些小问题！\n是否要打开材质包？")
                    # 确认则打开材质包文件
                    if exit_==True:
                        start="start \"\" "+"\"Skin_"+id_+'.zip'+"\""
                        os.system(start)
                    del exit_

            # 如果用户选择取消，则打开png文件
            else:
                try:
                    start=id_+'.png'
                    os.startfile(start)
                except:
                    pass

#多线程运行主函数，防止主线程GUI卡死
def getzb(ev=None):
     # 创建新线程来执行获取皮肤的主函数，避免GUI界面卡顿
    run_=threading.Thread(target=getzbmain)
    run_.start()
def info():#关于页面
    # 定义打开各个链接的函数
    def opengithub():
        os.startfile("https://github.com/NewbieXvwu/MinecraftSkinDownloader")
    def opengitee():
        os.startfile("https://gitee.com/NewbieXvwu/MinecraftSkinDownloader")
    def openbilibili():
        os.startfile("https://space.bilibili.com/505201154")
    # 创建关于窗口
    about=Toplevel()
    about.title("关于本程序")
    # 获取屏幕尺寸并计算窗口位置（居中显示）
    aboutscw=about.winfo_screenwidth()
    aboutsch=about.winfo_screenheight()
    aboutw=300
    abouth=210
    aboutx=(aboutscw-aboutw)/2
    abouty=(aboutsch-abouth)/2
    about.geometry("%dx%d+%d+%d"%(aboutw,abouth,aboutx,abouty))
    # 设置窗口图标
    try:
        about.iconbitmap('logo.ico')
    except:
        pass
    about.resizable(width=False,height=False) # 禁止调整窗口大小
    
    # 创建关于页面的UI组件
    lb4=Label(about,text="关于本程序",font=("宋体",15))
    lb4.place(x=100,y=30)
    
    # 根据操作系统调整文本显示
    if isLinux():
        lb5=Label(about,text="   这是一个可以简单地下载任何\n Minecraft正版玩家皮肤的软件。",font=("宋体",14))
    else:
        lb5=Label(about,text=" 这是一个可以简单地下载任何\n\n Minecraft正版玩家皮肤的软件。",font=("宋体",14))
    lb5.place(x=150,y=100,anchor=CENTER)
    
    # 创建链接按钮
    btn3=Button(about,text="Github",command=opengithub)
    btn3.place(x=200,y=155)
    btn4=Button(about,text="Gitee",command=opengitee)
    btn4.place(x=102,y=155)
    btn5=Button(about,text="Bilibili",command=openbilibili)
    btn5.place(x=0,y=155)
    
    about.lift() # 将关于窗口置于顶层
'''def TryUpdate(update_url):#更新模块，已禁用
    # 检查更新的功能，当前已被注释禁用
    update=requests.get(update_url)
    update=update.text
    update=json.loads(update)
    
    # 比较版本号
    if float(update["tag_name"])>version_int:
        assets=update["assets"]
        browser_download_url_list=assets[0]
        browser_download_url=browser_download_url_list["browser_download_url"]
        
        # 询问用户是否更新
        is_update=tkinter.messagebox.askyesno(title="检测到新版本", message="本程序有新版本！是否要下载？")
        if is_update==True:
            def autoupdate():
                # 禁用按钮并更新状态
                btn1.config(state=DISABLED)
                btn1.config(text="更新中……")
                zt.set("状态：更新中，请稍候……")
                
                # 创建更新批处理脚本
                fn=os.path.splitext(os.path.basename(__file__))[0]+os.path.splitext(os.path.basename(__file__))[1]
                with open("Update.bat", 'w') as file_object:
                    file_object.write("@echo off\ntaskkill -f -im python.exe\ntaskkill -f -im pythonw.exe\ntaskkill -f -im "+fn+"\ndel /s /q /f "+fn+"\nren New_MinecraftSkinDownloader.exe "+fn+"\nstart "+fn)
                
                # 下载新版本并执行更新
                urlretrieve(browser_download_url,"New_MinecraftSkinDownloader.exe")
                os.startfile("Update.bat")
                exit()
                
            # 在新线程中执行更新
            run_1=threading.Thread(target=autoupdate)
            run_1.start()
    del update'''
    
from tkinter import *
from ttkthemes import *
from tkinter.ttk import *

# 创建主题化的主窗口
#sc=ThemedTk(theme="equilux", toplevel=True, themebg=True) # 深色主题
sc= ThemedTk(theme="arc", toplevel=True, themebg=True)#使用ttkthemes的修改版Tk()
#窗口居中
scw=sc.winfo_screenwidth() # 屏幕宽度
sch=sc.winfo_screenheight() # 屏幕高度
w=500  # 窗口宽度
h=300  # 窗口高度
x=(scw-w)/2  # 窗口x坐标
y=(sch-h)/2  # 窗口y坐标
sc.title("Minecraft正版皮肤下载器"+version+" By 萌新欻無") # 设置窗口标题
sc.geometry("%dx%d+%d+%d"%(w,h,x,y)) # 设置窗口大小和位置
sc.maxsize(w,h) # 设置最大尺寸
sc.minsize(w,h)  # 设置最小尺寸
sc.resizable(width=False,height=False) # 禁止调整窗口大小
try:#从双源尝试下载Logo
    sc.iconbitmap('logo.ico')
except:
    try:
        urlretrieve("https://gitee.com/NewbieXvwu/MinecraftSkinDownloader/raw/main/logo.ico","logo.ico")
        sc.iconbitmap('logo.ico')
    except:
        try:
            urlretrieve("https://github.com/NewbieXvwu/MinecraftSkinDownloader/raw/main/logo.ico","logo.ico")
            sc.iconbitmap('logo.ico')
        except:
            pass  # 如果图标下载失败，忽略错误

try:
    ctypes.windll.shcore.SetProcessDpiAwareness(1)#高DPI适配
    ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(0)
    sc.tk.call('tk', 'scaling', ScaleFactor/75)
except:
    pass    # 如果不是Windows系统或适配失败，忽略错误
    
# 主屏幕组件初始化 
lb1=Label(sc,text="请输入Minecraft正版账号名称",font=("宋体",15))
lb1.place(x=110,y=50)

# 输入框
e=Entry(sc,width=20)
if isLinux():
    e.place(x=160,y=120)
else:
    e.place(x=170,y=120)
e.bind("<Return>",getzb)  # 绑定回车键事件
e.focus_set()  # 设置输入框焦点
btn1=Button(sc,text="点击获取",command=getzb)
btn1.place(x=195,y=190)

# 状态显示标签
# 创建一个tkinter字符串变量(StringVar)，用于动态更新标签文本
zt=tkinter.StringVar()

# 这个初始状态表示程序当前没有执行任何操作，等待用户输入
zt.set("状态：待命")

# 创建一个Label（标签）组件用于显示状态信息
lb2=Label(sc,textvariable=zt,font=("宋体",15))

# 根据操作系统类型设置标签的位置
if isLinux():
    lb2.place(x=10,y=265)
else:
    lb2.place(x=10,y=270)
    
# 主题选择下拉菜单
#cmb = Combobox(sc,width=7,state="readonly")
cmb = Menubutton(sc,width=7)
if isLinux():
    cmb.place(x=395,y=5)
else:
    cmb.place(x=400,y=5)
    
# 主题切换函数
def light():
    # 切换到浅色主题
    cmb.config(text="浅色模式")
    sc.set_theme("arc")
def dark():
    # 切换到深色主题
    cmb.config(text="深色模式")
    sc.set_theme("equilux")
    
# 创建主题选择菜单
filemenu = tkinter.Menu(cmb,tearoff=False)
filemenu.add_command(label="浅色模式",command=light)
filemenu.add_command(label="深色模式",command=dark)
cmb.config(menu=filemenu)
try:# 读取Windows 10深色模式
    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize")
    i = 0
    while True:
        #EnumValue方法用来枚举键值，EnumKey用来枚举子键
        name,value,type=winreg.EnumValue(key,i)
        if str(name)=="AppsUseLightTheme":
            break
        i +=1
    if value==0:  # 如果系统使用深色模式
        light() # 应用深色主题
    else:
        dark()  # 应用浅色主题
except:
    pass  # 如果不是Windows系统或读取失败，忽略错误
    
# 关于按钮
btn2=Button(sc,text="关于",command=info)  
if isLinux():
    btn2.place(x=390,y=255)
else:
    btn2.place(x=395,y=260)
    
# 版本号标签
lb3=Label(sc,text=version,font=("宋体",10))
lb3.place(x=5,y=5)

# 检查Python版本兼容性（针对Windows系统）
try:
    if float(str(platform.version().split(".")[0])+"."+str(platform.version().split(".")[1]))>6.3 and int(platform.python_version().split(".")[1])<=8:
        if tkinter.messagebox.askyesno(title="您正在使用过旧的Python", message="您的操作系统为Windows "+str(platform.version().split(".")[0])+"，\n但本程序正运行在版本为"+platform.python_version()+"的Python上。\n这可能是因为您下载了本程序的Windows 7特别版。\n使用特别版将会导致程序的稳定性无法得到保证，因为本程序的开发使用了更新的Python版本。\n您是否要下载一个稳定性更好的版本？"):
            os.startfile("https://github.com/NewbieXvwu/MinecraftSkinDownloader/releases")
            exit()
except:
    pass
if ispreview:#预览版警告
    if not tkinter.messagebox.askyesno(title="您正在使用预览版", message="您正在使用的版本为"+version+"，这是一个预览版。\n使用预览版可能会带来一些不可预知的问题！\n您是否要继续？"):
        os.startfile("https://github.com/NewbieXvwu/MinecraftSkinDownloader/releases")
        exit()
'''try:# 尝试检查更新（已禁用）
    TryUpdate("https://gitee.com/api/v5/repos/NewbieXvwu/MinecraftSkinDownloader/releases/latest")
except:
    try:
        TryUpdate("https://api.github.com/repos/NewbieXvwu/MinecraftSkinDownloader/releases/lates")
    except:
        pass'''
        
# 启动GUI主循环
sc.mainloop()  